/**
 * gislin 2017年7月18日
 */
package com.btcode.orm.relation;

import com.btcode.orm.model.IField;
import com.btcode.orm.model.IModel;

/**
 * 关联设计的思考
 * <br>
 * 关联分为：
 * <ul>
 * <li>一对一</li>
 * <li>一对多</li>
 * <li>多对多</li>
 * </ul>
 * <br>
 * 其中，<b>一对一</b>可以纳入<b>一对多</b>的范畴内
 * <br>
 * <b>多对多</b>可以分解为两个<b>一对多</b>的关系
 * <br>
 * 就是说，框架要可以处理这种组合关联，这样的话，上面的关联场景就都得到解决
 * <br>
 * <br>
 * 如何处理这种组合关联？针对上面提到的<b>多对多</b>,最初的设计是，一个在<b>IRelation</b>内再内嵌一个<b>IRelation</b>
 * <br>
 * <h3>这样处理</h3>
 * <ul>
 * <li>
 * 好处是:在执行关联查询的时候，比较明确，逻辑简单，外层的<b>IRelation</b>就是中间表，里层的<b>IRelation</b>就是最终要关联的业务表
 * </li>
 * <li>
 * 坏处是:处理复杂业务关联的时候，很别扭，比如那种很多层关联的情况
 * </li>
 * </ul>
 * 所以，这种设计不能沿用，考虑把复杂关联做成类似堆栈集合，而不是内嵌，来处理复杂关联
 * <br>
 * 这里分析关联的情况：
 * <br>
 * <pre>
 * 	select * from user t
 * 		left join user_role t1 on t.user_id = t1.user_id
 * 		left join role t2 on t1.role_id = t2.role_id
 *
 * 		left join org t3 on t3.org_id = t.org_i *
 * </pre>
 *
 * 上面这个sql有三个关联查询，但其实可以归纳为两个：
 * <ul>
 * <li>
 * 一个是，user和user_role、role的关联，这组关联，虽然有两个，但关联user_role的最终目的是为了让user和role关联，这个可以看成是一个关联，
 * <br>
 * 这里的情况可以更复杂，比如通过N个中间表最终关联到一个目标表，那么这一批都可以看成是一个关联
 * </li>
 * <li>
 * 另一个就简单了，就是和org的关联，没什么好说的，也看成是一个关联
 * </li>
 * </ul>
 *
 * 所以在处理关联关系的时候，把关联关系归纳为N个<b>大关联</b>,<b>大关联</b>里面可以包含N个<b>小关联</b>
 *
 * <br>
 * 没有再往深的关系了， 比如<b>小关联</b>里面不再有更深的<b>小小关联</b>，就算客观上有,如果这一系列的关联都是首位相连形成链条的，都认为是一组关联。
 * <br>
 *
 * 为了处理这种大关联套小关联的场景，设计出两个概念一个是IRelation，一个是Join，IRelation是大关联，而Join是小关联，N个IRelation可以组成一个virtualModel
 *
 * @author gislin 2017年7月18日
 */
public interface IRelation {

    /**
     * 获取关联语句 如：left join tableName on id = guid gislin 2017年7月18日
     */
    String getJoinText();

    /**
     * 获取关联类型 gislin 2017年7月18日
     */
    RelationType getRelationType();

    /**
     * 获取关联关系中的主表 gislin 2017年7月18日
     */
    String getMasterTableName();

    /**
     * 获取关联关系中的从表 gislin 2017年7月18日
     */
    String getSlaveTableName();

    /**
     * 获取主表的model类型 gislin 2017年7月28日
     */
    Class<IModel> getMasterModelClass();

    /**
     * 获取关联关系中主表的关联字段 gislin 2017年7月18日
     */
    IField getMasterField();

    /**
     * 获取从表的model类型 gislin 2017年7月28日
     */
    Class<IModel> getSlaveModelClass();

    /**
     * 获取关联关系中从表的关联字段，不设置的话，默认是从表的主键 gislin 2017年7月18日
     */
    IField getSlaveField();

    /**
     * 获取级联关联关系，用于支持多对多
     */
    IRelation getNextRelation();

    /**
     * 设置级联关联关系，用于支持多对多
     */
    void setNextRelation(IRelation relation);

    /**
     * 是否级联删除 gislin 2017年8月24日
     */
    boolean isRelationDelete();

    /**
     * 关联数据是否要缓存
     */
    boolean isNeedCache();

}
